/*     */ package com.zimbra.cs.mailbox;
/*     */ 
/*     */ import com.google.common.base.Strings;
/*     */ import com.google.common.collect.ImmutableList;
/*     */ import com.google.common.collect.Lists;
/*     */ import com.google.common.collect.Maps;
/*     */ import com.zimbra.common.localconfig.DebugConfig;
/*     */ import com.zimbra.common.mailbox.Color;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.db.Db;
/*     */ import com.zimbra.cs.db.DbMailItem;
/*     */ import com.zimbra.cs.db.DbMailbox;
/*     */ import com.zimbra.cs.db.DbPool;
/*     */ import com.zimbra.cs.db.DbPool.DbConnection;
/*     */ import com.zimbra.cs.db.DbTag;
/*     */ import com.zimbra.cs.db.DbUtil;
/*     */ import com.zimbra.cs.index.SortBy;
/*     */ import com.zimbra.cs.mailbox.acl.AclPushSerializer;
/*     */ import com.zimbra.cs.service.util.SyncToken;
/*     */ import java.security.SecureRandom;
/*     */ import java.sql.PreparedStatement;
/*     */ import java.sql.ResultSet;
/*     */ import java.sql.SQLException;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class MailboxUpgrade
/*     */ {
/*     */   private static final Map<Long, Byte> UPGRADE_TO_1_7_COLORS;
/*     */   private static final Map<Long, Byte> UPGRADE_TO_1_8_COLORS;
/*     */   
/*     */   static
/*     */   {
/*  56 */     UPGRADE_TO_1_7_COLORS = new HashMap();
/*  57 */     UPGRADE_TO_1_8_COLORS = UPGRADE_TO_1_7_COLORS;
/*     */     
/*     */ 
/*  60 */     Map<Long, Byte> map = UPGRADE_TO_1_7_COLORS;
/*     */     
/*  62 */     map.put(Long.valueOf(16777216L), Byte.valueOf((byte)0));
/*     */     
/*  64 */     map.put(Long.valueOf(16777471L), Byte.valueOf((byte)1));
/*  65 */     map.put(Long.valueOf(16810628L), Byte.valueOf((byte)2));
/*  66 */     map.put(Long.valueOf(25461380L), Byte.valueOf((byte)8));
/*  67 */     map.put(Long.valueOf(16810496L), Byte.valueOf((byte)3));
/*  68 */     map.put(Long.valueOf(33521664L), Byte.valueOf((byte)9));
/*  69 */     map.put(Long.valueOf(25428100L), Byte.valueOf((byte)4));
/*  70 */     map.put(Long.valueOf(33489028L), Byte.valueOf((byte)7));
/*  71 */     map.put(Long.valueOf(33488896L), Byte.valueOf((byte)5));
/*  72 */     map.put(Long.valueOf(25461248L), Byte.valueOf((byte)6));
/*     */     
/*  74 */     map.put(Long.valueOf(27178741L), Byte.valueOf((byte)1));
/*  75 */     map.put(Long.valueOf(27584230L), Byte.valueOf((byte)2));
/*  76 */     map.put(Long.valueOf(30659539L), Byte.valueOf((byte)8));
/*  77 */     map.put(Long.valueOf(26724529L), Byte.valueOf((byte)3));
/*  78 */     map.put(Long.valueOf(33406037L), Byte.valueOf((byte)9));
/*  79 */     map.put(Long.valueOf(33463251L), Byte.valueOf((byte)7));
/*  80 */     map.put(Long.valueOf(29001445L), Byte.valueOf((byte)4));
/*  81 */     map.put(Long.valueOf(33330838L), Byte.valueOf((byte)5));
/*  82 */     map.put(Long.valueOf(33552051L), Byte.valueOf((byte)6));
/*     */     
/*  84 */     map.put(Long.valueOf(16929492L), Byte.valueOf((byte)1));
/*  85 */     map.put(Long.valueOf(16810628L), Byte.valueOf((byte)2));
/*  86 */     map.put(Long.valueOf(25461380L), Byte.valueOf((byte)8));
/*  87 */     map.put(Long.valueOf(19702027L), Byte.valueOf((byte)3));
/*  88 */     map.put(Long.valueOf(32864258L), Byte.valueOf((byte)9));
/*  89 */     map.put(Long.valueOf(28321710L), Byte.valueOf((byte)7));
/*  90 */     map.put(Long.valueOf(21572513L), Byte.valueOf((byte)4));
/*  91 */     map.put(Long.valueOf(31790871L), Byte.valueOf((byte)5));
/*  92 */     map.put(Long.valueOf(25461248L), Byte.valueOf((byte)6));
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void upgradeTo1_7(Mailbox mbox)
/*     */     throws ServiceException
/*     */   {
/* 102 */     OperationContext octxt = new OperationContext(mbox);
/* 103 */     for (Folder folder : mbox.getFolderList(octxt, SortBy.NONE)) {
/* 104 */       Color color = folder.getRgbColor();
/* 105 */       if (!color.hasMapping()) {
/* 106 */         Byte value = (Byte)UPGRADE_TO_1_7_COLORS.get(Long.valueOf(color.getValue()));
/* 107 */         if (value != null) {
/* 108 */           Color newcolor = new Color(value.byteValue());
/* 109 */           mbox.setColor(octxt, new int[] { folder.getId() }, folder.getType(), newcolor);
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   public static void upgradeTo1_8(Mailbox mbox)
/*     */     throws ServiceException
/*     */   {
/* 119 */     OperationContext octxt = new OperationContext(mbox);
/* 120 */     for (Tag tag : mbox.getTagList(octxt)) {
/* 121 */       Color color = tag.getRgbColor();
/* 122 */       if (!color.hasMapping()) {
/* 123 */         Byte value = (Byte)UPGRADE_TO_1_8_COLORS.get(Long.valueOf(color.getValue()));
/* 124 */         if (value != null) {
/* 125 */           Color newcolor = new Color(value.byteValue());
/* 126 */           mbox.setColor(octxt, new int[] { tag.getId() }, tag.getType(), newcolor);
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   public static void upgradeTo2_0(Mailbox mbox) throws ServiceException {
/* 133 */     migrateHighestIndexed(mbox);
/*     */     
/*     */ 
/* 136 */     migrateContactGroups(mbox);
/*     */     
/*     */ 
/* 139 */     pushExistingFolderAclsToLdap(mbox);
/*     */   }
/*     */   
/*     */   private static void pushExistingFolderAclsToLdap(Mailbox mbox) throws ServiceException {
/* 143 */     List<Folder> folders = mbox.getFolderList(null, SortBy.NONE);
/* 144 */     Set<String> sharedItems = new HashSet();
/* 145 */     for (Iterator i$ = folders.iterator(); i$.hasNext();) { folder = (Folder)i$.next();
/* 146 */       ACL acl = folder.getACL();
/* 147 */       if (acl != null)
/*     */       {
/*     */ 
/* 150 */         for (ACL.Grant grant : acl.getGrants())
/* 151 */           sharedItems.add(AclPushSerializer.serialize(folder, grant)); }
/*     */     }
/*     */     Folder folder;
/* 154 */     if (!sharedItems.isEmpty()) {
/* 155 */       mbox.getAccount().setSharedItem((String[])sharedItems.toArray(new String[sharedItems.size()]));
/*     */     }
/*     */   }
/*     */   
/*     */   private static void migrateHighestIndexed(Mailbox mbox) throws ServiceException {
/* 160 */     DbPool.DbConnection conn = DbPool.getConnection(mbox);
/*     */     
/*     */ 
/*     */     try
/*     */     {
/* 165 */       String highestIndexed = null;
/* 166 */       PreparedStatement stmt = conn.prepareStatement("SELECT highest_indexed FROM " + DbMailbox.qualifyZimbraTableName(mbox, "mailbox") + " WHERE id = ?");
/*     */       
/* 168 */       stmt.setInt(1, mbox.getId());
/* 169 */       ResultSet rs = stmt.executeQuery();
/* 170 */       if (rs.next()) {
/* 171 */         highestIndexed = rs.getString(1);
/*     */       }
/* 173 */       rs.close();
/* 174 */       stmt.close();
/*     */       
/* 176 */       if (Strings.isNullOrEmpty(highestIndexed)) {
/*     */         return;
/*     */       }
/*     */       SyncToken token;
/*     */       try
/*     */       {
/* 182 */         token = new SyncToken(highestIndexed);
/*     */       }
/*     */       catch (ServiceException e)
/*     */       {
/*     */         return;
/*     */       }
/* 188 */       stmt = conn.prepareStatement("UPDATE " + DbMailItem.getMailItemTableName(mbox) + " SET index_id = 0 WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "mod_content > ? AND mod_metadata > ? AND index_id IS NOT NULL");
/*     */       
/*     */ 
/* 191 */       int pos = DbMailItem.setMailboxId(stmt, mbox, 1);
/* 192 */       stmt.setInt(pos++, token.getChangeId());
/* 193 */       stmt.setInt(pos++, token.getChangeId());
/* 194 */       stmt.executeUpdate();
/* 195 */       stmt.close();
/*     */       
/*     */ 
/* 198 */       stmt = conn.prepareStatement("UPDATE " + DbMailbox.qualifyZimbraTableName(mbox, "mailbox") + " SET highest_indexed = NULL WHERE id = ?");
/*     */       
/* 200 */       stmt.setInt(1, mbox.getId());
/* 201 */       stmt.executeUpdate();
/* 202 */       stmt.close();
/* 203 */       conn.commit();
/*     */     }
/*     */     catch (SQLException e) {
/* 206 */       throw ServiceException.FAILURE("Failed to migrate highest_indexed", e);
/*     */     } finally {
/* 208 */       conn.closeQuietly();
/*     */     }
/*     */   }
/*     */   
/*     */   public static void migrateContactGroups(Mailbox mbox) throws ServiceException {
/* 213 */     ContactGroup.MigrateContactGroup migrate = new ContactGroup.MigrateContactGroup(mbox);
/*     */     try {
/* 215 */       migrate.handle();
/* 216 */       ZimbraLog.mailbox.info("contact group migration finished for mailbox " + mbox.getId());
/*     */     } catch (Exception e) {
/* 218 */       ZimbraLog.mailbox.warn("contact group migration failed", e);
/*     */     }
/*     */   }
/*     */   
/*     */   public static void migrateFlagsAndTags(Mailbox mbox) throws ServiceException {
/* 223 */     DbPool.DbConnection conn = DbPool.getConnection(mbox);
/*     */     try {
/* 225 */       migrateFlagColumn(conn, mbox, true);
/* 226 */       migrateTagColumn(conn, mbox, true);
/*     */       
/*     */ 
/* 229 */       mbox.purge(MailItem.Type.TAG);
/*     */       
/*     */ 
/* 232 */       mbox.purge(MailItem.Type.CONTACT);
/* 233 */       conn.commit();
/*     */     }
/*     */     catch (ServiceException e) {
/* 236 */       throw e;
/*     */     } finally {
/* 238 */       conn.closeQuietly();
/*     */     }
/*     */   }
/*     */   
/*     */   public static void upgradeTo2_1(Mailbox mbox) throws ServiceException {
/* 243 */     DbPool.DbConnection conn = DbPool.getConnection(mbox);
/*     */     try {
/* 245 */       if (alreadyUpgradedTo2_1(conn, mbox)) {
/* 246 */         ZimbraLog.mailbox.warn("detected already-migrated mailbox %d during migration to version 2.1; skipping.", new Object[] { Integer.valueOf(mbox.getId()) });
/*     */       }
/*     */       else {
/* 249 */         for (Iterator i$ = Mailbox.REIFIED_FLAGS.iterator(); i$.hasNext();) { int tagId = ((Integer)i$.next()).intValue();
/* 250 */           DbTag.createTag(conn, mbox, Flag.of(mbox, tagId).mData, null, false);
/*     */         }
/* 252 */         migrateFlagColumn(conn, mbox, false);
/* 253 */         migrateTagColumn(conn, mbox, false);
/*     */         
/*     */ 
/*     */ 
/* 257 */         mbox.purge(MailItem.Type.TAG);
/*     */         
/*     */ 
/*     */ 
/* 261 */         mbox.purge(MailItem.Type.CONTACT);
/*     */       }
/* 263 */       conn.commit();
/*     */     }
/*     */     catch (ServiceException e) {
/* 266 */       throw e;
/*     */     } finally {
/* 268 */       conn.closeQuietly();
/*     */     }
/*     */   }
/*     */   
/*     */   private static boolean alreadyUpgradedTo2_1(DbPool.DbConnection conn, Mailbox mbox) throws ServiceException {
/* 273 */     PreparedStatement stmt = null;
/* 274 */     ResultSet rs = null;
/*     */     try {
/* 276 */       stmt = conn.prepareStatement("SELECT id FROM " + DbTag.getTagTableName(mbox) + (DebugConfig.disableMailboxGroups ? "" : " WHERE mailbox_id = ?"));
/*     */       
/* 278 */       int pos = 1;
/* 279 */       pos = DbMailItem.setMailboxId(stmt, mbox, pos);
/*     */       
/* 281 */       rs = stmt.executeQuery();
/* 282 */       return rs.next();
/*     */     } catch (SQLException e) {
/* 284 */       throw ServiceException.FAILURE("checking for repeated 2.1 upgrade for mbox " + mbox.getId(), e);
/*     */     } finally {
/* 286 */       DbPool.closeResults(rs);
/* 287 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   public static void upgradeTo2_3(Mailbox mbox)
/*     */     throws ServiceException
/*     */   {
/* 295 */     DbPool.DbConnection conn = DbPool.getConnection(mbox);
/* 296 */     PreparedStatement stmt = null;
/* 297 */     ResultSet rs = null;
/*     */     try {
/* 299 */       if (flagExists(conn, mbox, Flag.FlagInfo.PRIORITY)) {
/*     */         return;
/*     */       }
/*     */       
/* 303 */       DbTag.createTag(conn, mbox, Flag.FlagInfo.PRIORITY.toFlag(mbox).mData, null, false);
/*     */       
/* 305 */       List<Long> flagsets = getTagsets(conn, mbox, "flags");
/*     */       
/* 307 */       migrateColumnToTaggedItem(conn, mbox, "flags", Flag.ID_PRIORITY, matchTagsets(flagsets, Flag.BITMASK_PRIORITY), false);
/* 308 */       conn.commit();
/*     */     } catch (ServiceException e) {
/* 310 */       conn.rollback();
/* 311 */       throw e;
/*     */     } finally {
/* 313 */       conn.closeQuietly(rs);
/* 314 */       conn.closeQuietly(stmt);
/* 315 */       conn.closeQuietly();
/*     */     }
/*     */   }
/*     */   
/*     */   public static void upgradeTo2_4(Mailbox mbox) throws ServiceException
/*     */   {
/* 321 */     DbPool.DbConnection conn = DbPool.getConnection(mbox);
/*     */     try {
/* 323 */       if (flagExists(conn, mbox, Flag.FlagInfo.POST)) {
/*     */         return;
/*     */       }
/* 326 */       DbTag.createTag(conn, mbox, Flag.FlagInfo.POST.toFlag(mbox).mData, null, false);
/* 327 */       conn.commit();
/*     */     }
/*     */     catch (ServiceException e) {
/* 330 */       throw e;
/*     */     } finally {
/* 332 */       conn.closeQuietly();
/*     */     }
/*     */   }
/*     */   
/*     */   public static void upgradeTo2_7(Mailbox mbox) throws ServiceException
/*     */   {
/* 338 */     DbPool.DbConnection conn = DbPool.getConnection(mbox);
/*     */     try {
/* 340 */       if (flagExists(conn, mbox, Flag.FlagInfo.MUTED)) {
/*     */         return;
/*     */       }
/* 343 */       DbTag.createTag(conn, mbox, Flag.FlagInfo.MUTED.toFlag(mbox).mData, null, false);
/* 344 */       conn.commit();
/*     */     }
/*     */     catch (ServiceException e) {
/* 347 */       throw e;
/*     */     } finally {
/* 349 */       conn.closeQuietly();
/*     */     }
/*     */   }
/*     */   
/*     */   private static boolean flagExists(DbPool.DbConnection conn, Mailbox mbox, Flag.FlagInfo finfo) throws ServiceException
/*     */   {
/* 355 */     assert (Mailbox.REIFIED_FLAGS.contains(Integer.valueOf(finfo.id))) : "inserting non-reified flag";
/*     */     
/* 357 */     PreparedStatement stmt = null;
/* 358 */     ResultSet rs = null;
/*     */     try {
/* 360 */       stmt = conn.prepareStatement("SELECT COUNT(*) FROM " + DbTag.getTagTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "id = ?");
/*     */       
/* 362 */       int pos = DbMailItem.setMailboxId(stmt, mbox, 1);
/* 363 */       stmt.setInt(pos, finfo.id);
/* 364 */       rs = stmt.executeQuery();
/* 365 */       boolean bool; if ((rs.next()) && (rs.getInt(1) > 0)) {
/* 366 */         ZimbraLog.mailbox.debug(finfo.name() + " flag already exists");
/* 367 */         return true;
/*     */       }
/*     */       
/* 370 */       return false;
/*     */     } catch (SQLException e) {
/* 372 */       throw ServiceException.FAILURE("Failed to check for " + finfo.name() + " flag", e);
/*     */     } finally {
/* 374 */       conn.closeQuietly(rs);
/* 375 */       conn.closeQuietly(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   public static void upgradeTo2_5(Mailbox mbox)
/*     */     throws ServiceException
/*     */   {
/* 383 */     DbMailItem.assignUuids(mbox, false);
/*     */   }
/*     */   
/*     */   private static void migrateFlagColumn(DbPool.DbConnection conn, Mailbox mbox, boolean checkDuplicates) throws ServiceException
/*     */   {
/* 388 */     List<Long> flagsets = getTagsets(conn, mbox, "flags");
/*     */     
/*     */ 
/* 391 */     for (Iterator i$ = Mailbox.REIFIED_FLAGS.iterator(); i$.hasNext();) { int tagId = ((Integer)i$.next()).intValue();
/* 392 */       long bitmask = Flag.of(mbox, tagId).toBitmask();
/* 393 */       migrateColumnToTaggedItem(conn, mbox, "flags", tagId, matchTagsets(flagsets, bitmask), checkDuplicates);
/*     */     }
/*     */     
/*     */ 
/* 397 */     migrateColumnToTaggedItem(conn, mbox, "unread", Flag.ID_UNREAD, ImmutableList.of(Long.valueOf(1L)), checkDuplicates);
/*     */   }
/*     */   
/*     */   private static void migrateTagColumn(DbPool.DbConnection conn, Mailbox mbox, boolean checkDuplicates) throws ServiceException
/*     */   {
/* 402 */     Map<Integer, String> tagNames = createTagRows(conn, mbox, checkDuplicates);
/* 403 */     if (tagNames.isEmpty()) {
/* 404 */       return;
/*     */     }
/*     */     
/* 407 */     List<Long> tagsets = getTagsets(conn, mbox, "tags");
/* 408 */     if (tagsets.isEmpty()) {
/* 409 */       return;
/*     */     }
/*     */     
/* 412 */     for (Iterator i$ = tagNames.keySet().iterator(); i$.hasNext();) { int tagId = ((Integer)i$.next()).intValue();
/* 413 */       long bitmask = 1L << tagId - 64;
/* 414 */       migrateColumnToTaggedItem(conn, mbox, "tags", tagId, matchTagsets(tagsets, bitmask), checkDuplicates);
/*     */     }
/*     */     
/*     */ 
/* 418 */     calculateTagCounts(conn, mbox);
/*     */     
/*     */ 
/* 421 */     populateTagNameColumn(conn, mbox, tagNames, tagsets);
/*     */     
/*     */ 
/* 424 */     deleteTagRows(conn, mbox);
/*     */   }
/*     */   
/*     */   private static void migrateColumnToTaggedItem(DbPool.DbConnection conn, Mailbox mbox, String column, int tagId, List<Long> matches, boolean checkDuplicates) throws ServiceException
/*     */   {
/* 429 */     if (matches.isEmpty()) {
/* 430 */       return;
/*     */     }
/* 432 */     PreparedStatement stmt = null;
/*     */     try {
/* 434 */       String sql = "INSERT INTO " + DbTag.getTaggedItemTableName(mbox) + "(mailbox_id, tag_id, item_id)" + " SELECT " + DbMailItem.MAILBOX_ID_VALUE + "?, id FROM " + DbMailItem.getMailItemTableName(mbox) + " t1 WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type NOT IN " + DbMailItem.NON_SEARCHABLE_TYPES + " AND " + DbUtil.whereIn(column, matches.size());
/*     */       
/*     */ 
/*     */ 
/* 438 */       if (checkDuplicates) {
/* 439 */         sql = sql + " AND NOT EXISTS(SELECT mailbox_id, tag_id, item_id FROM " + DbTag.getTaggedItemTableName(mbox) + " t2 WHERE mailbox_id = ? AND tag_id = ? AND t2.item_id = t1.id)";
/*     */       }
/*     */       
/* 442 */       stmt = conn.prepareStatement(sql);
/* 443 */       int pos = 1;
/* 444 */       pos = DbMailItem.setMailboxId(stmt, mbox, pos);
/* 445 */       stmt.setInt(pos++, tagId);
/* 446 */       pos = DbMailItem.setMailboxId(stmt, mbox, pos);
/* 447 */       for (Iterator i$ = matches.iterator(); i$.hasNext();) { long match = ((Long)i$.next()).longValue();
/* 448 */         stmt.setLong(pos++, match);
/*     */       }
/* 450 */       if (checkDuplicates) {
/* 451 */         stmt.setInt(pos++, mbox.getId());
/* 452 */         stmt.setInt(pos++, tagId);
/*     */       }
/*     */       
/* 455 */       stmt.executeUpdate();
/*     */     } catch (SQLException e) {
/* 457 */       throw ServiceException.FAILURE("creating rows in TAGGED_ITEM for tag/flag " + tagId + " in mbox " + mbox.getId(), e);
/*     */     } finally {
/* 459 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   private static List<Long> getTagsets(DbPool.DbConnection conn, Mailbox mbox, String column) throws ServiceException {
/* 464 */     PreparedStatement stmt = null;
/* 465 */     ResultSet rs = null;
/*     */     try {
/* 467 */       stmt = conn.prepareStatement("SELECT DISTINCT(" + column + ") FROM " + DbMailItem.getMailItemTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type NOT IN" + DbMailItem.NON_SEARCHABLE_TYPES);
/*     */       
/* 469 */       DbMailItem.setMailboxId(stmt, mbox, 1);
/*     */       
/* 471 */       rs = stmt.executeQuery();
/* 472 */       List<Long> tagsets = Lists.newArrayList();
/* 473 */       while (rs.next()) {
/* 474 */         tagsets.add(Long.valueOf(rs.getLong(1)));
/*     */       }
/* 476 */       return tagsets;
/*     */     } catch (SQLException e) {
/* 478 */       throw ServiceException.FAILURE("getting distinct values for column '" + column + "' in mbox " + mbox.getId(), e);
/*     */     } finally {
/* 480 */       DbPool.closeResults(rs);
/* 481 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   private static List<Long> matchTagsets(List<Long> tagsets, long bitmask) {
/* 486 */     List<Long> matches = Lists.newArrayList();
/* 487 */     for (Iterator i$ = tagsets.iterator(); i$.hasNext();) { long tags = ((Long)i$.next()).longValue();
/* 488 */       if ((tags & bitmask) != 0L) {
/* 489 */         matches.add(Long.valueOf(tags));
/*     */       }
/*     */     }
/* 492 */     return matches;
/*     */   }
/*     */   
/*     */   private static String serializedTagset(long tags, Map<Integer, String> tagNames) {
/* 496 */     if (tags == 0L) {
/* 497 */       return null;
/*     */     }
/*     */     
/* 500 */     List<String> matches = Lists.newArrayList();
/*     */     
/* 502 */     for (int i = 0; i < 63; i++) {
/* 503 */       if ((tags & 1L << i) != 0L) {
/* 504 */         matches.add(tagNames.get(Integer.valueOf(64 + i)));
/*     */       }
/*     */     }
/* 507 */     return DbTag.serializeTags((String[])matches.toArray(new String[matches.size()]));
/*     */   }
/*     */   
/*     */   private static Map<Integer, String> createTagRows(DbPool.DbConnection conn, Mailbox mbox, boolean checkDuplicates) throws ServiceException {
/* 511 */     PreparedStatement stmt = null;
/* 512 */     ResultSet rs = null;
/*     */     try {
/* 514 */       stmt = conn.prepareStatement("SELECT id, name, mod_metadata, metadata FROM " + DbMailItem.getMailItemTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type = " + MailItem.Type.TAG.toByte());
/*     */       
/* 516 */       DbMailItem.setMailboxId(stmt, mbox, 1);
/*     */       
/* 518 */       rs = stmt.executeQuery();
/* 519 */       Map<Integer, String> tagNames = Maps.newHashMap();
/* 520 */       MailItem.UnderlyingData data; while (rs.next()) {
/* 521 */         data = new MailItem.UnderlyingData();
/* 522 */         data.id = rs.getInt(1);
/* 523 */         data.name = rs.getString(2);
/* 524 */         data.modMetadata = rs.getInt(3);
/* 525 */         Color color = Color.fromMetadata(new Metadata(rs.getString(4)).getLong("c", 0L));
/*     */         try
/*     */         {
/* 528 */           DbTag.createTag(conn, mbox, data, color.getMappedColor() == 0 ? null : color, true);
/*     */         } catch (ServiceException se) {
/* 530 */           if ((checkDuplicates) && (se.getCode().equals("mail.ALREADY_EXISTS")))
/*     */           {
/* 532 */             SecureRandom sr = new SecureRandom();
/* 533 */             data.name += sr.nextInt();
/* 534 */             DbTag.createTag(conn, mbox, data, color.getMappedColor() == 0 ? null : color, true);
/*     */           } else {
/* 536 */             throw se;
/*     */           }
/*     */         }
/*     */         
/* 540 */         tagNames.put(Integer.valueOf(data.id), data.name);
/*     */       }
/* 542 */       return tagNames;
/*     */     } catch (SQLException e) {
/* 544 */       throw ServiceException.FAILURE("creating TAG rows in mbox " + mbox.getId(), e);
/*     */     } finally {
/* 546 */       DbPool.closeResults(rs);
/* 547 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   private static void calculateTagCounts(DbPool.DbConnection conn, Mailbox mbox) throws ServiceException {
/* 552 */     PreparedStatement stmt = null;
/*     */     try {
/* 554 */       String mailboxesMatchAnd = DebugConfig.disableMailboxGroups ? "" : "ti.mailbox_id = mi.mailbox_id AND ";
/* 555 */       stmt = conn.prepareStatement("UPDATE " + DbTag.getTagTableName(mbox) + ", " + "(SELECT ti.tag_id tid, COUNT(ti.item_id) count, " + Db.clauseIFNULL("SUM(mi.unread)", "0") + " unread_count" + "  FROM " + DbTag.getTaggedItemTableName(mbox, "ti") + "  INNER JOIN " + DbMailItem.getMailItemTableName(mbox, "mi") + " ON " + mailboxesMatchAnd + "mi.id = ti.item_id" + "  WHERE " + DbTag.inThisMailboxAnd("ti") + "ti.tag_id > 0 AND " + Db.getInstance().bitAND("mi.flags", String.valueOf(Flag.BITMASK_DELETED)) + " = 0" + "  GROUP BY ti.tag_id) AS x" + " SET item_count = count, unread = unread_count WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "id = tid");
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 562 */       int pos = 1;
/* 563 */       pos = DbMailItem.setMailboxId(stmt, mbox, pos);
/* 564 */       pos = DbMailItem.setMailboxId(stmt, mbox, pos);
/*     */       
/* 566 */       stmt.executeUpdate();
/*     */     } catch (SQLException e) {
/* 568 */       throw ServiceException.FAILURE("deleting MAIL_ITEM tag rows in mbox " + mbox.getId(), e);
/*     */     } finally {
/* 570 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   private static void populateTagNameColumn(DbPool.DbConnection conn, Mailbox mbox, Map<Integer, String> tagNames, List<Long> tagsets) throws ServiceException
/*     */   {
/* 576 */     PreparedStatement stmt = null;
/*     */     try {
/* 578 */       StringBuilder update = new StringBuilder();
/* 579 */       for (int i = 0; i < tagsets.size(); i++) {
/* 580 */         update.append(" WHEN ? THEN ?");
/*     */       }
/* 582 */       stmt = conn.prepareStatement("UPDATE " + DbMailItem.getMailItemTableName(mbox) + " SET tag_names = CASE tags" + update + " END" + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type NOT IN" + DbMailItem.NON_SEARCHABLE_TYPES);
/*     */       
/*     */ 
/* 585 */       int pos = 1;
/* 586 */       for (Iterator i$ = tagsets.iterator(); i$.hasNext();) { long tags = ((Long)i$.next()).longValue();
/* 587 */         stmt.setLong(pos++, tags);
/* 588 */         stmt.setString(pos++, serializedTagset(tags, tagNames));
/*     */       }
/* 590 */       pos = DbMailItem.setMailboxId(stmt, mbox, pos);
/*     */       
/* 592 */       stmt.executeUpdate();
/*     */     } catch (SQLException e) {
/* 594 */       throw ServiceException.FAILURE("populating MAIL_ITEM.TAG_NAMES values in mbox " + mbox.getId(), e);
/*     */     } finally {
/* 596 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   private static void deleteTagRows(DbPool.DbConnection conn, Mailbox mbox) throws ServiceException {
/* 601 */     PreparedStatement stmt = null;
/*     */     try {
/* 603 */       stmt = conn.prepareStatement("DELETE FROM " + DbMailItem.getMailItemTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type = " + MailItem.Type.TAG.toByte());
/*     */       
/* 605 */       DbMailItem.setMailboxId(stmt, mbox, 1);
/*     */       
/* 607 */       stmt.executeUpdate();
/*     */     } catch (SQLException e) {
/* 609 */       throw ServiceException.FAILURE("deleting MAIL_ITEM tag rows in mbox " + mbox.getId(), e);
/*     */     } finally {
/* 611 */       DbPool.closeStatement(stmt);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailbox/MailboxUpgrade.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */